<html>
<head>
  <title>node.js 3.2——模板引擎</title>
  <basefont face="微软雅黑" size="2" />
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <meta name="exporter-version" content="YXBJ Windows/607344 (zh-CN, DDL); Windows/10.0.0 (Win64); EDAMVersion=V2;"/>
  <meta name="content-class" content="yinxiang.superNote"/>
  <style>
    body, td {
      font-family: 微软雅黑;
      font-size: 12pt;
    }
  </style>
</head>
<body>
<a name="17811"/>
<h1>node.js 3.2——模板引擎</h1>

<div><span><h1>简介</h1><ul><li><div>常见的模板引擎</div></li><ul><li><div>art-template，可以在node和浏览器中使用，它是一个高性能的模板引擎</div></li><li><div><a href="http://aui.github.io/art-template/zh-cn/docs/" rev="en_rl_none">art-template文档</a></div></li></ul></ul><h1>使用示例</h1><h2>原生服务器</h2><ul><li><div>安装</div></li></ul><div style="--en-codeblock:true;--en-codeblockLanguage:clike;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">npm install art-template --registry=https://registry.npm.taobao.org</div><ul><li><div>js文件中引入art-template模块</div></li></ul><div style="--en-codeblock:true;--en-codeblockLanguage:clike;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">const http = require('http');
const fs = require('fs')
const template = require('art-template')
const server = http.createServer();
server.on('request', (req, res) =&gt; {
  fs.readFile('./index.html', (err, data) =&gt; {
    if (err) {
      res.end(&quot;没有找到文件&quot;);
    } else {
      let ret = template.render(data.toString(),{
        name:'Jack',
        age:18,
        province:'北京市',
        hobbies:[
          '写代码',
          '唱歌',
          '打游戏'
        ]
      })
      console.log(ret)
      res.setHeader('Content-Type', 'text/html;charset=utf-8');
      res.end(ret)
    }
  });

});
server.listen(3000, () =&gt; {
  console.log('服务器建立成功，请访问：&quot;' + '127.0.0.1:3000&quot;');
});</div><ul><li><div>index.html</div></li></ul><div style="--en-codeblock:true;--en-codeblockLanguage:clike;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;

&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
  &lt;p&gt;大家好,我叫{{name}}&lt;/p&gt;
  &lt;p&gt;今年，我{{age}}岁了&lt;/p&gt;
  &lt;h1&gt;我来自{{province}}&lt;/h1&gt;
  &lt;p&gt;我喜欢：{{each hobbies}}{{$value}} {{/each}}&lt;/p&gt;
&lt;/body&gt;

&lt;/html&gt;</div><h2>express服务器</h2><ul><li><div>安装</div></li></ul><div style="--en-codeblock:true;--en-codeblockLanguage:javascript;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">npm i --save art-template
npm i --save express-art-template</div><ul><li><div>server.js</div></li><ul><li><div>需要对 app 进行配置</div></li><li><div>调用res.render 方法来加载模板文件</div></li><li><div><b>模板文件必须放置在</b><span style="background-color: #fff199;"><b>项目的views路径下</b></span><b>，并且以.art为后缀名（可以在app.engine中更改）</b></div></li></ul></ul><div style="--en-codeblock:true;--en-codeblockLanguage:javascript;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">const express = require('express');

// 创建服务器
const app = express();
// 使用 art-template 模板引擎
// 第一个参数指定渲染文件的后缀名，推荐使用.art结尾，和html静态文件区分开
app.engine('art',require('express-art-template')); //这句必须有
app.set('view options',{ // 这里是可选的配置
  debug: process.env.NODE_ENV !== 'production' // debug模式在非生产环境下启动
})

// 将对/public/的访问的url改为本文件下的/public/
app.use('/public/',express.static('./public/'));

app.get('/index',(req,res)=&gt;{
  // 这里的第一个参数的后缀名，必须和app.engine的第一个参数匹配
  res.render('index.art',{
    name:'张三',
    age:15,
    province:'浙江',
    hobbies:['唱','跳','Rap','篮球']
  });
});

app.listen(8080,()=&gt;{
  console.log('请访问: 127.0.0.1:8080');
})</div><div><br/></div><h1>语法规则</h1><h2>输出</h2><ul><li><div>template.render(str,{})</div></li><ul><li><div>将str 中的满足标准语法的语句替换为对象中的变量</div></li></ul></ul><div style="--en-codeblock:true;--en-codeblockLanguage:clike;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">// 直接写变量名
{{value}}
// 指定对象的子对象
{{data.key}}
// 指定对象的某个属性
{{data['key']}}
// 三元表达式
{{a ? b : c}}
// 
{{a || b}}
{{a + b}}</div><h2>条件判断</h2><div style="--en-codeblock:true;--en-codeblockLanguage:clike;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">// 满足条件时显示中间的内容
{{if value}} ... {{/if}}
// 多条件
{{if v1}} ... {{else if v2}} ... {{/if}}</div><h2>循环</h2><div>遍历数组</div><div style="--en-codeblock:true;--en-codeblockLanguage:javascript;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">{{each list}}
当前索引:{{$index}}
当前遍历的对象:{{$value}}
{{each}}</div><div>遍历对象：</div><div style="--en-codeblock:true;--en-codeblockLanguage:python;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">{{each obj}}
    {{$value}}
{{/each}}</div><div><br/></div><h2> 定义变量</h2><div style="--en-codeblock:true;--en-codeblockLanguage:clike;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">{{set temp = data.sub.content}}</div><h2>模板间的继承</h2><div style="--en-codeblock:true;--en-codeblockLanguage:clike;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">{{extend './layout.art'}}

{{block 'head'}} ... {{/block}}</div><ul><li><div>示例:</div></li><li><div>模板</div></li></ul><div style="--en-codeblock:true;--en-codeblockLanguage:clike;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">&lt;!--layout.art--&gt;
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
    &lt;title&gt;{{block 'title'}}My Site{{/block}}&lt;/title&gt;

    {{block 'head'}}
    &lt;link rel=&quot;stylesheet&quot; href=&quot;main.css&quot;&gt;
    {{/block}}
&lt;/head&gt;
&lt;body&gt;
    {{block 'content'}}{{/block}}
&lt;/body&gt;
&lt;/html&gt;</div><ul><li><div>继承</div></li></ul><div style="--en-codeblock:true;--en-codeblockLanguage:clike;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">&lt;!--index.art--&gt;
{{extend './layout.art'}}

{{block 'title'}}{{title}}{{/block}}

{{block 'head'}}
    &lt;link rel=&quot;stylesheet&quot; href=&quot;custom.css&quot;&gt;
{{/block}}

{{block 'content'}}
&lt;p&gt;This is just an awesome page.&lt;/p&gt;
{{/block}}</div><div><br/></div><h2>引号处理</h2><div>引号会被特殊处理，所以要替换回来</div><div style="--en-codeblock:true;--en-codeblockLanguage:javascript;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">let ret = template.render(sqltmplt,obj)
ret = ret.replace(/&amp;#34;/g,&quot;\&quot;&quot;).replace(/&amp;#60;/g,&quot;&lt;&quot;).replace(/&amp;#62;/g,&quot;&gt;&quot;)</div><div><br/></div><h1>模板工具</h1><div style="--en-codeblock:true;--en-codeblockLanguage:javascript;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;">const fs = require('fs');
const template = require('art-template')
const fileUtils = require(&quot;E:/重要文件/BaiduNetdiskWorkspace/nodejs_utils/fileUtils&quot;)

module.exports = {
    /**
     * 读取xlsx,返回数据和title
     * @param {string} xlsxPath 
     * @param {number} sheet 
     * @returns 
     */
    readXlsx (xlsxPath, sheet) {
        let datas = fileUtils.excelGetData(xlsxPath, sheet === undefined ? 0 : sheet)
        let title = fileUtils.getExcelTitle(datas)
        let objArr = fileUtils.excelToObj(datas)
        return {
            data: objArr,
            title
        }
    },
    /**
     * 渲染模板
     * @param {string} tmplt 
     * @param {object} params 
     * @returns 
     */
    getTemplate (tmplt, params) {
        return template.render(tmplt, {
            params
        }).replace(/&amp;#34;/g, &quot;\&quot;&quot;).replace(/&amp;#60;/g,&quot;&lt;&quot;).replace(/&amp;#62;/g,&quot;&gt;&quot;)
    },
    /**
     * 输出文件
     * @param {string} str 
     * @param {string} outPath 
     */
    outFile(str,outPath){
        const fd = fs.openSync(outPath, &quot;w&quot;);
        fs.writeSync(fd,str)
    }
}</div><div><br/></div></span>
</div></body></html> 